#include "PacMan.h"


PacMan::PacMan(void)
	:Character	(PACMAN)
	,mScore		(0)
	,mLives		(7)
	,mExternMBehavior(false)

	,mLoopAnim(0)
	,NUM_LOOP_ANIM(50)
{

	mImages[UP]    = new Bitmap("data\\pacman_u.tga");
	mImages[DOWN]  = new Bitmap("data\\pacman_d.tga");
	mImages[LEFT]  = new Bitmap("data\\pacman_l.tga");
	mImages[RIGHT] = new Bitmap("data\\pacman_r.tga");

	this->mImage		= mImages[RIGHT];
	this->mSpecImage	= mImage;
	this->mMoveBehavior	= new Wandering();

	CreateAnimation();
}
PacMan::PacMan(InputController* inputCtrl)
	:Character	(PACMAN)
	,mScore		(0)
	,mLives		(7)
	,mExternMBehavior(true)

	,mLoopAnim(0)
	,NUM_LOOP_ANIM(50)
{
	mImages[UP]    = new Bitmap("data\\pacman_u.tga");
	mImages[DOWN]  = new Bitmap("data\\pacman_d.tga");
	mImages[LEFT]  = new Bitmap("data\\pacman_l.tga");
	mImages[RIGHT] = new Bitmap("data\\pacman_r.tga");

	this->mImage		= mImages[RIGHT];
	this->mSpecImage	= mImage;
	this->mMoveBehavior	= inputCtrl;

	CreateAnimation();
}

PacMan::~PacMan(void)
{
	//detach();//inputController
	DestroyAnimation();
	if(!mExternMBehavior) delete mMoveBehavior;
	for(int i = 0; i < PROXIMITY_COUNT; i++)
	{
		delete mImages[i];
	}
	//delete mImage;//debug assertion
}

void PacMan::CreateAnimation() //creates an animation. 
{
	mPmAnimImg = new Bitmap("data\\pacMan_an1.tga"); 
	int indices[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 

	int indicesCount = sizeof(indices) / sizeof(int); 
	mPmAnim = new Animation(mPmAnimImg, 16, 16, indices, indicesCount, 0.15f); 
	//then, we'll start the animation. It will update itself on its own. 
	mPmAnim->Start(true);
}
void PacMan::DestroyAnimation()
{
	delete mPmAnim;
	delete mPmAnimImg;
}
void PacMan::moveTo(const Background* bg, BackgroundElement* nTile)
{
	if(nTile->isWalkable() && nTile->occupiedByPacMan == false)
	{
		bg->getTile(mTileIndex)->occupiedByPacMan = false;
		Character::moveTo(bg, nTile);
	}
}

void PacMan::setupProximity(const Background* bg, BackgroundElement* tile)
{
	if(mActive) tile->occupiedByPacMan = true;
	else		tile->occupiedByPacMan = false;
	Character::setupProximity(bg, tile);
}

void PacMan::move(Background* bg)
{
	Proximity_dir facing = mMoveBehavior->getFacing();

	mMoveBehavior->perform(this, bg);

	if(mFacing != facing && facing < PROXIMITY_COUNT)
	{
		mFacing		= facing;
		mImage		= mImages[mFacing];
		mSpecImage  = mImage;
	}
}
//void PacMan::attach(InputController* inputCtrl)
//{
//	if(mMoveBehavior != nullptr)
//		delete mMoveBehavior;
//	mMoveBehavior = inputCtrl;
//}
//void PacMan::detach()
//{
//	if(mMoveBehavior != nullptr)
//		delete mMoveBehavior;
//}

void PacMan::collisionWith(GameEntity* entity, bool specialActive)
{
	if(entity->getType() == GHOST)
	{
		if(specialActive)
		{
			mScore += entity->getPoint();
		}
		else
		{
			deactivate();
			mRemainLoops = mLoopToRespawn;
		}
	}else{
		mScore += entity->getPoint();
	}
}

void PacMan::deactivate()
{
	mCurrentTile->occupiedByPacMan = false;
	if(this->mActive) 
		this->mActive = false;
	--mLives;
	mLoopAnim = NUM_LOOP_ANIM;
}

void PacMan::activate()
{
	mCurrentTile->occupiedByPacMan = true;
	Character::activate();
}

void PacMan::DrawTo(Bitmap* renderTarget, const bool specialActive, const int x, const int y)
{
	Character::DrawTo(renderTarget, specialActive, x, y);
	if(mLoopAnim > 0){
		mPmAnim->Draw(renderTarget, x + mXcoord, y + mYcoord);
		--mLoopAnim;
	}
}
void PacMan::DrawTo(Bitmap* renderTarget, const int x, const int y)
{
	Character::DrawTo(renderTarget, x, y);
	if(mLoopAnim > 0){
		mPmAnim->Draw(renderTarget, x + mXcoord, y + mYcoord);
		--mLoopAnim;
	}
}